#region COPYRIGHT
//--------------------------------------------------------------------------------
// <copyright file="TextInputTracker.cs" company="starLiGHT Entertainment Studios">
//    Copyright (c) 2011 
//       Roland Rosenkranz (Glatzemann@email.de)
// </copyright>
// <license>
//   This file is part of starLiGHT.GUI.
//
//   It is released under the Microsoft Public License (Ms-PL).
//
//   You should have received a copy of the Microsoft Public License
//   along with starLiGHT.GUI. If not, see http://sle.codeplex.com/license.
//    
//   ADDITIONAL (commercial) LICENSES for starLiGHT.GUI are available on request.
// </license>
// <version>
// **************[ starLiGHT.Engine SVN ]**********************
// * $Rev:: 9659                  $:  Revision of last commit *
// * $Author:: unknown            $:  Author of last commit   *
// * $Date:: 2011-05-04 12:33:30 #$:  Date of last commit     *
// ************************************************************
// </version>
//--------------------------------------------------------------------------------
#endregion

namespace starLiGHT.GUI.Input
{
    #region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    #endregion

    public abstract class TextInputTracker
    {
        private bool isTracking = false;
        private string text = string.Empty;
        private int caretPosition = 0;

        public event Action<string> TextChanged;

        public event Action<int> CaretPositionChanged;

        public event Func<char, bool> CharacterValidCheck;

        public string Text
        {
            get 
            { 
                return this.text; 
            } 

            protected set
            {
                this.text = value;
                this.OnTextChanged(); 
            }
        }

        public int CaretPosition 
        {
            get
            { 
                return this.caretPosition;
            } 

            set 
            {
                int before = this.caretPosition;
                this.caretPosition = (int)MathHelper.Clamp(value, 0, this.text.Length);

                if (this.caretPosition != before && this.CaretPositionChanged != null)
                {
                    this.CaretPositionChanged(this.caretPosition);
                }
            } 
        }

        protected bool IsTracking
        {
            get
            {
                return this.isTracking;
            }

            set
            {
                this.isTracking = value;
            }
        }

        public void StartTracking()
        {
            this.StartTracking(string.Empty, 0);
        }

        public void StartTracking(string text)
        {
            if (text == null)
            {
                text = string.Empty;
            }

            this.StartTracking(text, text.Length);
        }

        public virtual void StartTracking(string text, int caretPosition)
        {
            this.text = text;
            this.caretPosition = caretPosition;
            this.isTracking = true;
        }

        public virtual void StopTracking()
        {
            this.isTracking = false;
        }

        public void AddLetter(char letter)
        {
            if (!this.isTracking)
            {
                return;
            }

            if (this.CharacterValidCheck != null && !this.CharacterValidCheck(letter))
            {
                return;
            }

            if (this.caretPosition != this.text.Length)
            {
                this.Text = this.text.Insert(this.CaretPosition, letter.ToString());
            }
            else
            {
                this.Text += letter.ToString();
            }

            this.CaretPosition++;
        }

        public void Backspace()
        {
            if (this.caretPosition > 0)
            {
                this.Text = this.text.Remove(this.CaretPosition - 1, 1);
                this.CaretPosition--;
            }
        }

        public void Delete()
        {
            if (this.caretPosition < this.text.Length)
            {
                this.Text = this.text.Remove(this.CaretPosition, 1);
            }
        }

        public abstract void Update(GameTime gameTime);

        private void OnTextChanged()
        {
            if (this.TextChanged != null)
            {
                this.TextChanged(this.text);
            }
        }
    }
}
